/**
 * @file SURF_Homography
 * @brief SURF detector + descriptor + FLANN Matcher + FindHomography
 * @author A. Huaman
 */

#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/features2d.hpp"

#include "opencv2/opencv_modules.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/stitching/detail/autocalib.hpp"
#include "opencv2/stitching/detail/blenders.hpp"
#include "opencv2/stitching/detail/camera.hpp"
#include "opencv2/stitching/detail/exposure_compensate.hpp"
#include "opencv2/stitching/detail/matchers.hpp"
#include "opencv2/stitching/detail/motion_estimators.hpp"
#include "opencv2/stitching/detail/seam_finders.hpp"
#include "opencv2/stitching/detail/util.hpp"
#include "opencv2/stitching/detail/warpers.hpp"
#include "opencv2/stitching/warpers.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include "opencv2/calib3d/calib3d.hpp"

using namespace std;
using namespace cv;
using namespace cv::detail;

/**
 * @function main
 * @brief Main function
 */
int main( int argc, char** argv )
{
	Ptr<FeaturesFinder> finder;
	vector<Mat> images(2);
	vector<ImageFeatures> features(2);

	//read images
	//Mat image0=imread("image0.jpg");
	//Mat image1=imread("image1.jpg");
	Mat image0=imread("Cam1_0.jpg");
	Mat image1=imread("Cam2_0.jpg");

	//test rotating image
//	Mat source,trans;
//
//	source=imread("image38-2.jpg");
//	transpose(source,trans);
//
//	imshow("source",source);
//	imshow("dst",trans);

//	Mat grey0;
//	Mat grey1;
//
//	cvtColor(image0,grey0,CV_BGR2GRAY);
//	cvtColor(image1,grey1,CV_BGR2GRAY);
//
//	images[0]=grey0;
//	images[1]=grey1;

	images[0]=image0;
	images[1]=image1;

	finder=new SurfFeaturesFinder();

	(*finder)(images[0],features[0]);
	(*finder)(images[1],features[1]);

	finder->collectGarbage();

	//vector<MatchesInfo> pairwise_matches;
	MatchesInfo pairwise_matches;
	BestOf2NearestMatcher matcher(false,0.48f);

	//matcher(features,pairwise_matches);
	//matcher.operator ()(features,pairwise_matches);
	matcher.operator ()(features[0],features[1],pairwise_matches);
	matcher.collectGarbage();

	//-- Draw matches
	Mat img_matches;
	//drawKeypoints(image0, features[0].keypoints, img_matches, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
	//drawMatches(image0,features[0].keypoints,image1,features[1].keypoints,pairwise_matches[1].matches,img_matches);
	drawMatches(image0,features[0].keypoints,image1,features[1].keypoints,pairwise_matches.matches,img_matches);

	//cout<<pairwise_matches.size();

	//-- Show detected matches
	imshow("Matches", img_matches);

	// Use the Homography Matrix to warp the images
	Mat result;

	warpPerspective(image0,result,pairwise_matches.H,Size(image0.cols+image1.cols,image0.rows));
	//warpPerspective(image0,result,pairwise_matches.H,Size(image0.cols,image0.rows));

	imshow("image0",result);

	Mat half(result,Rect(0,0,image0.cols,image0.rows));

	image1.copyTo(half);

	imshow( "Result", result );

	waitKey(0);

	return 0;
}

